﻿using DataChangeTools.WebApi.Common;
using System.Data;

namespace DataChangeTools.WebApi.DAL
{
    /// <summary>
    /// dal基类
    /// </summary>
    public abstract class IBasicsDal<T> where T : class, new()
    {

        /// <summary>
        /// dapper帮助类
        /// </summary>
        public DapperHelper dapper;

        /// <summary>
        /// sql拼接结构体
        /// </summary>
        public SqlStruct<T> sqlStruct;

        /// <summary>
        /// 构造函数
        /// </summary>
        protected IBasicsDal()
        {
            this.dapper = new DapperHelper();
        }

        #region 基类虚方法,基本操作方法
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="index"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public virtual Tuple<List<T>, int> GetPageList(int index, int size)
        {
            List<T> list = dapper.ExecuteQuerys<T>(DisposeSql()).ToList();
            return new Tuple<List<T>, int>(list.Skip((index - 1) * size).Take(size).ToList(), list.Count);
        }

        /// <summary>
        /// 获取列表
        /// </summary>
        /// <returns></returns>
        public virtual List<T> GetList()
        {
            return dapper.ExecuteQuerys<T>(DisposeSql()).ToList();
        }

        /// <summary>
        /// 根据id获取列表
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T GetListById(int id)
        {
            return dapper.ExecuteQuery<T>(DisposeSql(id));
        }

        /// <summary>
        /// 根据参数获取列表
        /// </summary>
        /// <param name="param"></param>
        /// <returns></returns>
        public virtual List<T> GetListByParam(Dictionary<bool, Dictionary<string, string>> param)
        {
            return dapper.ExecuteQuerys<T>(DisposeSql(0, param)).ToList();
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Add(T entity)
        {
            return Convert.ToBoolean(dapper.ExecuteNonQuery(DisposeSql(0, entity: entity), entity));
        }

        /// <summary>
        /// 新增返回id
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual int AddResultId(T entity)
        {
            return DapperHelper.AddResultId<T>(DisposeSql(0, entity: entity, type: 1));
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual bool Delete(int id)
        {
            return dapper.ExecuteNonQuery<T>(DisposeSql(id, type: 2), null) > 0 ? true : false;
        }

        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public virtual bool Deletes(dynamic[] ids)
        {
            return dapper.ExecuteNonQuery<T>(DisposeSql(0, null, null, ids, 2), null) > 0 ? true : false;
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public virtual bool Edit(T entity)
        {
            return dapper.ExecuteNonQuery(DisposeSql(0, null, entity, null, 3), entity) > 0 ? true : false;
        }

        /// <summary>
        /// 批量新增
        /// </summary>
        /// <param name="entityList"></param>
        /// <returns></returns>
        public virtual bool AddList(List<T> entityList)
        {
            foreach (var item in entityList)
            {
                var result = SqlHelper<T>.Add(item);
                if (!result) return result;
            }
            return true;
        }
        #endregion

        #region 事务操作
        /// <summary>
        /// 新增并返回id带事务
        /// </summary>
        /// <param name="Sql"></param>
        /// <param name="conn"></param>
        /// <param name="tran"></param>
        /// <returns></returns>
        public int TranAddResultId(string Sql, IDbConnection conn, IDbTransaction tran)
        {
            //int id = dapper.AddResultId<ProjectEntity>(Sql, conn, tran);//新增后获取id
            //return id;
            return 0;
        }

        /// <summary>
        /// 事务操作(未开启)
        /// </summary>
        /// <param name="tranDic">1：新增，2：删除，3：修改</param>
        /// <returns></returns>
        public bool TranEntity(Dictionary<int, string> tranDic)
        {
            DapperHelper dapper = new DapperHelper();
            using (IDbConnection conn = dapper.GetConn())
            {
                IDbTransaction tran = null;
                try
                {
                    dapper.OpenConn(conn);//打开连接
                    tran = dapper.BeginTransaction(conn);//开启事务
                    //循环处理数据库操作
                    foreach (var item in tranDic)
                    {
                        switch (item.Key)
                        {
                            case 1://新增
                                dapper.ExecuteNonQuery(item.Value, conn, tran);
                                break;
                            case 2://删除
                                dapper.ExecuteNonQuery(item.Value, conn, tran);
                                break;
                            case 3://修改
                                dapper.ExecuteNonQuery(item.Value, conn, tran);
                                break;
                            default:
                                break;
                        }
                    }
                    dapper.Commit(tran);//提交事务
                    return true;
                }
                catch (Exception)//异常回滚
                {
                    dapper.Rollback(tran);
                    return false;
                }
                finally
                {
                    if (conn != null)
                    {
                        dapper.DisposeConn(conn);//销毁连接
                    }
                    if (tran != null)
                    {
                        dapper.Dispose(tran);//销毁事务
                    }
                }
            }
        }

        /// <summary>
        /// 事务操作(已开启)
        /// </summary>
        /// <param name="tranDic">1：新增，2：删除，3：修改</param>
        /// <returns></returns>
        public bool TranEntity(Dictionary<int, string> tranDic, IDbConnection conn, IDbTransaction tran)
        {
            if (conn == null || tran == null) return false;
            try
            {
                //循环处理数据库操作
                foreach (var item in tranDic)
                {
                    dapper.ExecuteNonQuery(item.Value, conn, tran);
                }
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
        #endregion

        /// <summary>
        /// 处理sql
        /// </summary>
        /// <param name="id"></param>
        /// <param name="param"></param>
        /// <param name="entity"></param>
        /// <param name="ids"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public string DisposeSql(int id = 0, Dictionary<bool, Dictionary<string, string>>? param = null, T? entity = null, dynamic[]? ids = null, int type = 0)
        {
            sqlStruct = new SqlStruct<T>();
            sqlStruct.Id = id;
            sqlStruct.Param = param;
            sqlStruct.Entity = entity;
            sqlStruct.Ids = ids;
            switch (type)
            {
                case 1:
                    sqlStruct.IsReturnId = true;
                    break;
                case 2:
                    sqlStruct.IsDelete = true;
                    break;
                case 3:
                    sqlStruct.IsUpdate = true;
                    break;
                default: break;
            }
            string sql = SqlHelper<T>.GetSql(sqlStruct);
            return sql;
        }
    }
}
